#!/usr/bin/python
# -*- coding: utf-8 -*-

import SimpleHTTPServer
from urlparse import urlparse, parse_qs
import RPi.GPIO as GPIO
import urllib2
import pexpect
import threading, Queue
import xml.etree.ElementTree as ET
import SerialThread
import ExerciseThread
import SocketServer
import CommandThread     
                
#shared memory
class SharedData():
    work = Queue.Queue(0)
    _const = {}
    _debug = False
    lock = threading.Lock()
    tid = []    
    
    def read_config(self):
        
        tree = ET.parse("configure.xml")
        #tree = ET.parse("configure.xml")
        root = tree.getroot()        
        
        for data in root.findall('data'):
            if data.attrib['debug'] == 'True':
                self._debug = True
                self._const["debug"] = True
            else:
                self._debug = False
                self._const["debug"] = False
                
            for element in data._children:
                if(len(element.attrib) == 0):
                    try:
                        self._const[element.tag] = int(element.text)
                    except:
                        self._const[element.tag] = float(element.text)
                else:
                    if element.tag == 'rpi_mode':
                        if element.text == 'server':
                            self._const[element.tag] = 1
                        elif element.text == 'client':
                            self._const[element.tag] = 2
                        elif element.text == 'combo':   
                            self._const[element.tag] = 3
                        else:
                            self._const[element.tag] = 0 
                    elif element.tag == 'client_IP':                        
                        self._const[element.tag] = {}
                        ips = self._const[element.tag]
                        for child_node in element:                            
                            ips[child_node.tag] = child_node.text
                    elif element.tag == 'checkpoint':
                        for child_node in element:
                            keypoint = child_node.tag
                            self._const[keypoint] = int(child_node.text)
                            keypoint = keypoint[2:4] + keypoint[0:2]
                            self._const[keypoint] = int(child_node.text)
                    else:
                        self._const[element.tag] = element.text
        del root
        del tree
        
        if(self._debug):
            print('const value = %s' % self._const)

class HttpHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):                           
    def do_GET(self):
        parsed_path = urlparse(self.path)
        urlquery = parsed_path.query.split('&')
        
        for query in urlquery:
            token = query.split('=')
            
            if token[0] == 'xls':
                #filename = parsed_path.query
                #self.cmd_excel_convert(token[1])
                sharedData.work.put(CommandThread.Command('xls', token[1], None, None))
            elif token[0] == 'relay':
                GPIO.setmode(GPIO.BOARD)
                GPIO.setwarnings(False)
                GPIO.setup(7, GPIO.OUT)
                if token[1] == 'on':
                    GPIO.output(7, GPIO.HIGH)
                else:
                    GPIO.output(7, GPIO.LOW)
               
                self.wfile.write('relay ' + token[1])
            elif token[0] == 'update':
                sharedData.work.put(CommandThread.Command('update', token[1], -1, -1))
                self.wfile.write('update cmd received')

            elif token[0] == 'reset_timer':
                sharedData.work.put(CommandThread.Command('reset_timer', token[1], 0, 23))
                self.wfile.write('reset timer now')
                
            elif token[0] == 'status':
                
                for t in sharedData.tid:
                    self.wfile.write(str('%s is %s<br>' % (t, t.isAlive())))
            elif token[0] == 'test':
                sharedData.work.put(CommandThread.Command('test', None, None, None))
                self.wfile.write('go test scpDB')

    
    
sharedData = SharedData() 

if __name__ == '__main__':

    sharedData.read_config()
    ExerciseThread._const = sharedData._const
    
    #when rpi_mode is 2(client) or 3(combo), PI creates SerialThreads that is responsible for receiving TagID.
    if sharedData._const['rpi_mode'] == 2 or sharedData._const['rpi_mode'] == 3:
        
        #create exercise thread which handle all exercise record
        exercise_thread = ExerciseThread.Exercise_Thread()         
        #detect how many devices and then initialize serial port(rs485)
        SerialThread.serial_init()
        
        #create thread for every serial port
        portname = ['b1', 'a1', 'a2', 'b2', 'd1', 'c1', 'c2', 'd2']
        
        for i in range(len(SerialThread.device_port)):
            sharedData.tid.append(SerialThread.Serial_Thread())
            sharedData.tid[i].init(SerialThread.device_port[i], exercise_thread._rawdata_record[portname[i]], portname[i], sharedData.lock)
            exercise_thread._portname.append(portname[i])     
         
        sharedData.tid.append(exercise_thread)
        
    #create sql thread which manage when and what record will be written into database 
    sql_thread = ExerciseThread.SQL_Thread()
    sql_thread.init()
    sharedData.tid.append(sql_thread)
    
    #if system is server or client, create additional threads to handle the communication between server and client.
    if sharedData._const['rpi_mode'] != 3:
        #create command thread which manage all commands received from http protocol
        command_thread = CommandThread.Command_Thread()
        CommandThread.work = sharedData.work
        command_thread._const = sharedData._const
        command_thread.resetTimer()
        command_thread.init(sql_thread)
        sharedData.tid.append(command_thread)    
        
        for t in sharedData.tid:
            t.start()        
        
        PORT = 8011
        SocketServer.TCPServer.allow_reuse_address = True
        httpd = SocketServer.TCPServer((sharedData._const['current_IP'], PORT), HttpHandler)
        httpd.allow_reuse_address = True
        httpd.serve_forever()
        
